package cz.muni.fi.pv112.cranesimulator.scene;

import cz.muni.fi.pv112.cranesimulator.scene.handlers.SceneHandler;
import cz.muni.fi.pv112.cranesimulator.scene.items.CameraMode;
import cz.muni.fi.pv112.cranesimulator.settings.Controls;
import cz.muni.fi.pv112.cranesimulator.utils.handlers.inputs.KeyInputHandler;
import java.util.Iterator;
import java.util.Map;

/**
 *
 * @author Michal Ďuriš
 */
public class SceneKeyInputApplier {

    private final KeyInputHandler keyInputHandler;
    private final Controls controls = Controls.getInstance();

    private final SceneHandler sceneHandler;

    private final CameraKeyInputApplier cameraKeyInputApplier;

    public SceneKeyInputApplier(KeyInputHandler keyInputHandler,
                                SceneHandler sceneHandler) {

        this.keyInputHandler = keyInputHandler;
        this.sceneHandler = sceneHandler;

        cameraKeyInputApplier = new CameraKeyInputApplier();
    }

    public void applyKeyInputs(boolean cameraMovementOnly) {

        if (cameraMovementOnly) {
            cameraKeyInputApplier.applyKeyInputs();
            return;
        }

        for (Iterator<Map.Entry<Integer, Boolean>> it = keyInputHandler
                .getKeymapView(); it.hasNext();) {

            Map.Entry<Integer, Boolean> keymapEntry = it.next();

            switch (controls.getControlsKey(keymapEntry.getKey())) {
                case FREE_CAMERA_MODE:
                    if (keymapEntry.getValue()) {
                        sceneHandler.changeCameraMode(
                                CameraMode.FREE_CAMERA_MODE);
                    }
                    break;
                case CABIN_CAMERA_MODE:
                    if (keymapEntry.getValue()) {
                        sceneHandler.changeCameraMode(
                                CameraMode.CABIN_CAMERA_MODE);
                    }
                    break;
                case MAGNET_CAMERA_MODE:
                    if (keymapEntry.getValue()) {
                        sceneHandler.changeCameraMode(
                                CameraMode.LIFTING_ROD_CAMERA_MODE);
                    }
                    break;
                case RIDER_FORWARD:
                    if (keymapEntry.getValue()) {
                        sceneHandler.moveLiftingRiderForward();
                    }
                    break;
                case RIDER_BACKWARD:
                    if (keymapEntry.getValue()) {
                        sceneHandler.moveLiftingRiderBackward();
                    }
                    break;
                case OPERATION_PART_ROTATION_LEFT:
                    if (keymapEntry.getValue()) {
                        sceneHandler.rotateCraneLeft();
                    }
                    break;
                case OPERATION_PART_ROTATION_RIGHT:
                    if (keymapEntry.getValue()) {
                        sceneHandler.rotateCraneRight();
                    }
                    break;
                case MAGNET_UP:
                    if (keymapEntry.getValue()) {
                        sceneHandler.moveMagnetUp();
                    }
                    break;
                case MAGNET_DOWN:
                    if (keymapEntry.getValue()) {
                        sceneHandler.moveMagnetDown();
                    }
                    break;
                case MAGNET_ENABLED:
                    if (keymapEntry.getValue()) {
                        sceneHandler.catchLiftableObject();
                    }
                    break;
                default:
            }
        }
    }

    private class CameraKeyInputApplier {

        private boolean isSomeCameraMovementKeyPressed() {

            return (keyInputHandler.isKeyPressed(
                    controls.getControlsKeyMapping(
                            Controls.Key.MOVE_CAMERA_FORWARD))
                    || keyInputHandler.isKeyPressed(
                            controls.getControlsKeyMapping(
                                    Controls.Key.MOVE_CAMERA_BACKWARD))
                    || keyInputHandler.isKeyPressed(
                            controls.getControlsKeyMapping(
                                    Controls.Key.MOVE_CAMERA_LEFT))
                    || keyInputHandler.isKeyPressed(
                            controls.getControlsKeyMapping(
                                    Controls.Key.MOVE_CAMERA_RIGHT)));
        }

        private void applyKeyInputs() {

            if (isSomeCameraMovementKeyPressed()) {

                boolean moveCameraLeftPressed = keyInputHandler.isKeyPressed(
                        controls.getControlsKeyMapping(
                                Controls.Key.MOVE_CAMERA_LEFT));
                boolean moveCameraRightPressed = keyInputHandler.isKeyPressed(
                        controls.getControlsKeyMapping(
                                Controls.Key.MOVE_CAMERA_RIGHT));
                boolean moveCameraForwardPressed = keyInputHandler.isKeyPressed(
                        controls.getControlsKeyMapping(
                                Controls.Key.MOVE_CAMERA_FORWARD));
                boolean moveCameraBackwardPressed = keyInputHandler
                        .isKeyPressed(
                                controls.getControlsKeyMapping(
                                        Controls.Key.MOVE_CAMERA_BACKWARD));

                float cameraMoveStep = sceneHandler.getActualCamera()
                        .getMoveStep();

                sceneHandler.moveCameraBy((moveCameraLeftPressed
                        && moveCameraRightPressed
                        ? 0.0f : moveCameraLeftPressed
                        ? cameraMoveStep : moveCameraRightPressed
                        ? -cameraMoveStep : 0.0f),
                        0.0f,
                        (moveCameraForwardPressed
                        && moveCameraBackwardPressed
                        ? 0.0f : moveCameraForwardPressed
                        ? cameraMoveStep
                        : moveCameraBackwardPressed
                        ? -cameraMoveStep : 0.0f));
            }
        }

    }

}
